let f = (a, b) => {a + b}
let f = (a, b) => { a }

let f = (a, b) => {
  a + b
}

let f = (a, b) => {
  a
}

let x = { a }
let x = { a + b }

let x = {
  // here
  a
}


let x = {
  // here
  a + b
}

let _ = { a }

let _ = { "constant" }

let _ = { () => Js.log("test") }
let _ = { switch b { | true => () | false => () } }
let _ = switch { b } { | true => () | false => () }
let _ = { apply(a, b) }
let _ =  {apply}(a, b) 

let _ = { try danger() catch { | Exit => () } }
let _ = try { danger() } catch { | Exit => () }

let _ = ({a}, {b}, {x + y})
let _ = { ({a}, {b}, {x + y})}

let _ = { Rgb(r, g, b) }
let _ = Rgb({r}, {g}, {b})
let _ = Rgb({
  r}, {
    g}, {
      b})

let _ = { {name:  "steve", age: 30 } }
let _ =  {name:  {"steve"}, age: {30} } 
let _ =  {name:  {
"steve"}, age: {
  30} } 

let _ = { user.name }.toString()
let _ = { { user.name }.toString() }
let _ = { user.name }.first
let _ = { { user.name }.first }

let _ = { [a, b, c] }
let _ =  [{a}, {b}, {c}] 
let _ =  [{
  a}, {
    b}, {
      c}] 

let _ = { list{a, b, c} }
let _ = { list{{a}, {b}, {c}} }
let _ = { list{{
  a}, {
    b}, {
      c}} }

let _ = list{1, 2, ...{list2}}

let _ = {true} ? {true} : {false}
let _ = {{true} ? {true} : {false}}

let _ = { if true { () } else { () } }
let _ = { if { true } { () } else { () } }

if {
  true
} { ()} else if {
  false
}  { () } 

if {
  true
} { ()} else if {
  false
}  { () } else { () }


let _ = { while true { () } }
let _ = while { true } { () }
while { /* c0 */ true /* c1 */ } { () }
while { 
  true
} { () }
while { 
  /* c0 */ true // c1
} { () }


let _ = { for _ in { 0 } to { 10 } { () } }
for _ in {
  0 } to {
    10 } { () }

let _ = {(foo: string)}
let f = () => {(foo: string)} // equivalent to  (): string => ...

let localToGlobalX = (
  x: coordinate<localCoordinates>,
  ~centering: coordinate<localCoordinates>,
): coordinate<globalCoordinates> => {
  x +. (Environment.width /. 2. -. centering.x)
}
map((
  arr,
  i,
): coordinate<globalCoordinates> => {
  x +. (Environment.width /. 2. -. centering.x)
})

let _ = assert({ true })
let _ = { assert({ true }) }

let _ = { %extension }
let _ = { module(ME) }
let _ = { module(ME: MyMod) }

{myArray}[{0}]
{
  myArray}[{
    0}]
{myArray}[{0}] = {20}
{
  myArray}[{
    0}] = {
      20}

myArray[20] = {
  a + b
}

{jsObject}["foo"]
{jsObject}["foo"] = { "bar" }
{jsObject}["foo"] = {
  a + b
}

{
  jsObject}["foo"]
{jsObject}["foo"] = { "bar" }

apply({a}, {b}, {c})
apply({
  a}, {
    b}, {
      c})

Thing.map(foo,(arg1, arg2) => {MyModuleBlah.toList(argument)})
Thing.map({foo},(arg1, arg2) => {
  MyModuleBlah.toList(argument)
})

Thing.map({fooSuperLongIdentifierName},{fooSuperLongIdentifierName}, {fooSuperLongIdentifierName},(arg1, arg2) => {
  MyModuleBlah.toList(argument)
})

arr->Belt.Array.map(x => {
  a
})

apply(~a={a})
apply({
  a
})
apply(.{
  a
})

let x = { <div> child </div> }

// not valid jsx
let x = { @JSX child  }

let x = {
  // comment1
  a + b
}

let x = {
  // commment2
  !truth
}

{
  /* c0 */
  x
  /* c1 */
}

{
  // comment
  a + b
}

{a} + {b}
{
  a} + {
    b}

// string constant should be printed correct
<> {"\n"->React.string} </>
<> {"\""->React.string} </>
